
#include "StdAfx.h"
#include "NetLibs.h"
#include <StaticProcessInfo.h>
#include <StringObj.h>
#include <tinyxml.h>
#include <LogService.h>

NetworkStat::NetworkStat(){
	active_ = false;
}

NetworkStat::~NetworkStat(){

}

bool NetworkStat::initialize( char* name ){

#ifdef WIN32
	data_ = new WinShareMemory< STSharedNetworkStat >();
#endif
#ifdef LINUX
	data_ = new UnixShareMemory< STSharedNetworkStat >();
#endif

	std::string strName;

	if( name )
		strName = name;
	else 
		strName = "noname";

	if( strName == "noname" )
		return false;
	
	strName += "_network";

	int iResult = data_->create( 1, strName.c_str() );
	
	if( iResult == ShareMemory<STSharedNetworkStat>::DEF_SHM_CREATE_FAIL ){
		LOG_ERR( LOG_SERVICE( "instance" )->Log("fail net_stat shared memory = %s", strName.c_str() ) );		
		return false;
	}
	
	if( iResult == ShareMemory<STSharedNetworkStat>::DEF_SHM_CREATE_ALREADY ){
		LOG_INSTANCE( LOG_SERVICE( "instance" )->Log("already exist net_stat shared memory = %s", strName.c_str() ) );		
		return true;
	}

	STSharedNetworkStat* pData = 0;
	pData = data_->get( 0 );
		
	if(! pData )
		return false;

	memset( pData, 0, sizeof( STSharedNetworkStat ) );

	LOG_INSTANCE( LOG_SERVICE( "instance" )->Log("create net_stat shared memory = %s", strName.c_str() ) );
	
	active_ = true;

	StaticProcessInfo::Instance()->register_shared_name( (char*)data_->getName(), StaticProcessInfo::DEF_SHARED_MEMORY_TYPE_NETWORK );
	
	return true;
}

int NetworkStat::add_ping_close(){
	if(! active_ )
		return DEFAULT_FAIL;

	STSharedNetworkStat* pData = data_->get(0);
	if (!pData)
		return DEFAULT_FAIL;

	pData->ping_close_count_++;

	return DEFAULT_SUCCESS;
}


int NetworkStat::set( int session, int pool_buffers, int msg_buffers ){
	if(! active_ )
		return DEFAULT_FAIL;

	STSharedNetworkStat* pData = data_->get(0);
	if (!pData)
		return DEFAULT_FAIL;

	pData->sessions_ = session;
	pData->pool_buffers_ = pool_buffers;
	pData->msg_buffers_ = msg_buffers;
	pData->main_loop_++;

	return DEFAULT_SUCCESS;

}

#ifdef WIN32
#pragma comment( lib, "tinyxml.lib" )
#endif

NetworkConfig::NetworkConfig(){
	listen_port_ = 0;
	loop_cycle_ = 0;
	worker_count_ = 0;
	life_cycle_limit_ = 0;
	dead_cycle_limit_ = 0;
	forced_poller_ = "none";
}

NetworkConfig::NetworkConfig( NetworkConfig& config ){
	listen_port_ = config.listen_port_;
	loop_cycle_ = config.loop_cycle_;
	worker_count_ = config.worker_count_;
	dead_cycle_limit_ = config.dead_cycle_limit_;
	life_cycle_limit_ = config.life_cycle_limit_;
	max_session_ = config.max_session_;
	poller_type_ = config.poller_type_;	

	if(! forced_poller_.size() )
		forced_poller_ = "none";
}

NetworkConfig::~NetworkConfig(){
}

void NetworkConfig::set_environment( int listen_port, int loop_cycle, int worker_count, \
	int max_session, int life_cycle_limit )
{
	listen_port_ = listen_port;
	loop_cycle_ = loop_cycle;
	worker_count_ = worker_count;
	max_session_ = max_session;
	life_cycle_limit_ = life_cycle_limit;
}

void NetworkConfig::poller_type( int type ){
	poller_type_ = type;
}

bool NetworkConfig::get_environment( const std::string& fileName ){	
	LOG_INSTANCE( LOG_SERVICE( "instance" )->Log("* network initialize value : file name = %s", fileName) );

	TiXmlDocument doc( fileName.c_str() );

	if( doc.LoadFile() == false ){
		int iLine = doc.ErrorRow();
		int iCol = doc.ErrorCol();
		
		LOG_ERR( LOG_SERVICE( "instance" )->Log("config file load fail! : %d/%d",iLine,iCol) );

		return false;
	}

	if( doc.Error() ){		
		LOG_ERR( LOG_SERVICE( "instance" )->Log("%s - %u", __FUNCTION__, __LINE__) );
		return false;
	}

	TiXmlNode* node = 0;
	TiXmlNode* tmp_node = 0;
	TiXmlElement* element = doc.RootElement();
	
	StringObj value;
	value = (char*)element->Value();	
	if(! value.isEqualIgnLetterType("config") ){
		LOG_ERR( LOG_SERVICE( "instance" )->Log("%s - %u", __FUNCTION__, __LINE__) );
		return false;
	}
	
	node = element->FirstChild("server");
	value = node->FirstChild("listen")->FirstChild()->Value();
	listen_port_ = value.to4ByteNumber();		
	LOG_INSTANCE( LOG_SERVICE( "instance" )->Log(" - listen port = %u", listen_port_) );		

	value = node->FirstChild("loop_cycle_tick")->FirstChild()->Value();
	loop_cycle_ = value.to4ByteNumber();
	IS_NULL_RETURN(loop_cycle_, false);	
	LOG_INSTANCE( LOG_SERVICE( "instance" )->Log(" - loop cycle = %u", loop_cycle_) );

	value = node->FirstChild("worker_count")->FirstChild()->Value();
	worker_count_ = value.to4ByteNumber();	
	LOG_INSTANCE( LOG_SERVICE( "instance" )->Log(" - worker count = %u", worker_count_) );

	value = node->FirstChild("life_cycle_limit")->FirstChild()->Value();
	life_cycle_limit_ = value.to4ByteNumber();		
	LOG_INSTANCE( LOG_SERVICE( "instance" )->Log(" - life cycle limit = %u", life_cycle_limit_) );
	
	tmp_node = node->FirstChild("dead_limit_sec");
	if( tmp_node ){
		value = tmp_node->FirstChild()->Value();
		dead_cycle_limit_ = value.to4ByteNumber();	
		LOG_INSTANCE( LOG_SERVICE( "instance" )->Log(" - dead limit sec = %u", dead_cycle_limit_ ) );
	}	

	value = node->FirstChild("max_session")->FirstChild()->Value();
	max_session_ = value.to4ByteNumber();		
	LOG_INSTANCE( LOG_SERVICE( "instance" )->Log(" - max_session = %u", max_session_) );	
	
	tmp_node = node->FirstChild("forced_poller_set");
	if( tmp_node ){
		forced_poller_ = tmp_node->FirstChild()->Value();

		if( forced_poller_ == "select" )
			poller_type_ = DEF_POLLER_SELECT;
		else if( forced_poller_ == "iocp" )
			poller_type_ = DEF_POLLER_IOCP;
		else if( forced_poller_ == "epoll" )
			poller_type_ = DEF_POLLER_EPOLL;
	}
	
	LOG_INSTANCE( LOG_SERVICE( "instance" )->Log(" - forced poller set = %s", forced_poller_.c_str()) );
	LOG_INSTANCE( LOG_SERVICE( "instance" )->Log("-------------------------------") );

	return true;
}
